package com.zz.bid.service;

import com.zz.bid.entity.Group;
import com.zz.bid.entity.User;
import com.zz.bid.exception.ChangePwdAuthException;
import com.zz.bid.exception.LoginException;
import com.zz.bid.exception.LoginTimeoutException;
import com.zz.bid.exception.base.BidException;
import com.zz.bid.mapper.GroupMapper;
import com.zz.bid.mapper.UserMapper;
import com.zz.bid.to.UserTO;
import com.zz.bid.util.EhcacheMapper;
import com.zz.bid.util.JWTHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private GroupMapper groupMapper;

    @Autowired
    private EhcacheMapper ehcacheMapper;

    public UserTO authenticate(String account, String inputPwd) throws BidException {
        User user = userMapper.getUser(account);
        //TODO 未加密
        if (null == user || !user.getPwd().equals(inputPwd)) {
            throw new LoginException();
        }

        Group group = groupMapper.getGroup(user.getGroupId());

        String token = UUID.randomUUID().toString();

        String jwtToken = JWTHandler.encodeJwt(token);

        UserTO userTO = UserTO.builder().accountName(user.getAccount()).access(group.getOperation().split(",")).groupId(group.getId()).token(jwtToken).build();

        ehcacheMapper.set(token, userTO);

        return userTO;
    }

    public void logout(String token) throws BidException {
        try {
            ehcacheMapper.remove(JWTHandler.decodeJwt(token));
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new BidException(e.getMessage());
        }
    }

    public UserTO getUserInfo(String jwtToken) throws LoginTimeoutException {
        UserTO userTO = ehcacheMapper.get(JWTHandler.decodeJwt(jwtToken));
        if (null == userTO) {
            throw new LoginTimeoutException();
        }
        return userTO;
    }

    public List<UserTO> getUsers() throws BidException {
        try {
            List<User> users = userMapper.getUsers();
            if (null != users) {
                return users.stream().map(item -> UserTO.builder().accountName(item.getAccount())
                        .admin(item.getAdmin()).groupId(item.getGroupId()).groupName(item.getGroupName()).banned(item.getBanned()).build()).collect(Collectors.toList());
            } else {
                return new ArrayList<>();
            }
        } catch (Exception e) {
            throw new BidException(e.getMessage());
        }
    }


    public void addUser(String account, String password, Integer groupId, Integer useAble) throws BidException {
        try {
            userMapper.addUser(account, password, groupId, useAble);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new BidException(e.getMessage());
        }
    }

    public void updatePwd(String account, String oldPwd, String newPwd) throws BidException {
        try {
            User user = userMapper.getUser(account);
            if (!user.getPwd().equals(oldPwd)) {
                throw new ChangePwdAuthException();
            }

            userMapper.setPwd(user.getId(), newPwd);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new BidException(e.getMessage());
        }
    }
}
